/** 
 * extras.c - Various GUI extensions for WoodPecker
 *
 * WoodPecker is the legal property of its developers, whose names are too numerous
 * to list here.  Please refer to the COPYRIGHT file distributed with this
 * source distribution.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * $Id: extras.c 136 2008-05-03 06:27:18Z dubkat $
 */

#define PURPLE_PLUGINS
#include "extras.h"

/* Show icons in chat room windows */

void
get_icon_scale_size(GdkPixbuf * icon, PurpleBuddyIconSpec * spec, int *width, int *height)
{
    g_return_if_fail(icon != NULL);
    *width = gdk_pixbuf_get_width(icon);
    *height = gdk_pixbuf_get_height(icon);
    /* purple_debug_misc("popups", "current: w: %i, h: %i\n", *width, *height); */
    /* this should eventually get smarter about preserving the aspect ratio when scaling, but
       gimmie a break, I just woke up */
    if(spec && spec->scale_rules & PURPLE_ICON_SCALE_DISPLAY)
    {
        float spec_aspect = (float) spec->max_width / (float) spec->max_height;
        float icon_aspect = (float) (*width) / (float) (*height);

        // icon will hit borders horizontally first
        if(icon_aspect > spec_aspect)
        {
            float width_ratio = (float) (*width) / (float) (spec->max_width);

            *height = (float) (*height) / width_ratio;
            *width = spec->max_width;
        }
        if(icon_aspect < spec_aspect)
        {
            float height_ratio = (float) (*height) / (float) (spec->max_height);

            *width = (float) (*width) / height_ratio;
            *height = spec->max_height;
        }
    }

    /* and now for some arbitrary sanity checks */
    if(*width > 100)
        *width = 100;
    if(*height > 100)
        *height = 100;
    /* purple_debug_misc("popups", "scaled: w: %i, h: %i\n", *width, *height); */
}

/* Adds motion handlers to IM tab labels.*/
static void
redo_im_window(PurpleConversation * c)
{

    if(!g_strrstr(purple_account_get_protocol_id(c->account), "prpl-pecker"))
        return;

    purple_debug_misc("chaticon", "GOT CONVERSATION CREATED FOR %s\n", c->name);

    /*
       if(c && c->type == PURPLE_CONV_TYPE_IM)
       add_im_popup_stuff(c);
     */
    if(c->type == PURPLE_CONV_TYPE_CHAT)
    {
        add_chat_sort_functions(c);
        //add_chat_popup_stuff(c);
        //add_chat_icon_stuff(c);
    }

}


static void
update_info_cb(PurpleAccount * account, char *name)
{
    if(!g_strrstr(purple_account_get_protocol_id(account), "prpl-pecker"))
        return;
    purple_debug_misc("wood", "info update\n");
}

static gchar *
find_file(const char *dir, const char *base)
{
    char *filename;

    if(base == NULL)
        return NULL;

    if(!strcmp(dir, "pidgin"))
    {
        //purple_debug_misc("wood", "looking for " DATADIR "/pixmaps/pidgin/" base "\n");
        filename = g_build_filename(DATADIR, "pixmaps", "pidgin", base, NULL);
    }
    else
    {
        filename = g_build_filename(DATADIR, "pixmaps", "pidgin", dir, base, NULL);
    }

    if(!g_file_test(filename, G_FILE_TEST_EXISTS))
    {
        g_critical("Unable to load stock pixmap %s\n", filename);

        g_free(filename);

        return NULL;
    }

    return filename;

}

void
extras_register_stock()
{

    static gboolean stock_is_init = FALSE;
    GtkIconFactory *icon_factory = NULL;
    int i;

    if(stock_is_init)
        return;
    stock_is_init = TRUE;
    icon_factory = gtk_icon_factory_new();

    gtk_icon_factory_add_default(icon_factory);

    for (i = 0; i < G_N_ELEMENTS(stock_icons); i++)
    {
        GdkPixbuf *pixbuf;
        GtkIconSet *iconset;
        gchar *filename;

        filename = find_file(stock_icons[i].dir, stock_icons[i].filename);
        if(filename == NULL)
            continue;

        pixbuf = gdk_pixbuf_new_from_file(filename, NULL);
        g_free(filename);
        iconset = gtk_icon_set_new_from_pixbuf(pixbuf);

        g_object_unref(pixbuf);
        gtk_icon_factory_add(icon_factory, stock_icons[i].name, iconset);
        gtk_icon_set_unref(iconset);
    }
}

GdkPixbuf *
lookup_cached_thumbnail(PurpleAccount * account, const char *fullname)
{
    gsize len;
    int i;

    PurpleBuddyIcon *icon = purple_buddy_icons_find(account, fullname);

    if(!icon)
    {
        purple_debug_misc("wood", "No icon found for %s\n", fullname);
        return NULL;
    }
    const guchar *icon_bytes = purple_buddy_icon_get_data(icon, (gsize *) len);

    if(!icon_bytes)
    {
        purple_debug_misc("wood", "No icon data found for %s\n", fullname);
        return NULL;
    }

    GError *err = NULL;
    GdkPixbufLoader *loader = gdk_pixbuf_loader_new();

    if(!gdk_pixbuf_loader_write(loader, icon_bytes, len, &err))
        purple_debug_misc("roombrowse", "write error: %s\n", err->message);
    else
        purple_debug_misc("roombrowse", "write %d bytes without errors.\n", len);
    GdkPixbuf *pixbuf = gdk_pixbuf_loader_get_pixbuf(loader);
    GdkPixbufFormat *format = gdk_pixbuf_loader_get_format(loader);

    if(format)
    {
        purple_debug_misc("roombrowse", "pixbuf name: %s\n", gdk_pixbuf_format_get_name(format));
        //purple_debug_misc("roombrowse","pixbuf domain: %s\n", gdk_pixbuf_format_get_domain(format));
        purple_debug_misc("roombrowse", "pixbuf description: %s\n", gdk_pixbuf_format_get_description(format));

        gchar **mime_types = gdk_pixbuf_format_get_mime_types(format);
        gchar **extensions = gdk_pixbuf_format_get_extensions(format);

        i = 0;
        while (mime_types[i] != NULL)
            purple_debug_misc("roombrowse", "pixbuf mime_type: %s\n", mime_types[i++]);

        i = 0;
        while (extensions[i] != NULL)
            purple_debug_misc("roombrowse", "pixbuf extensions: %s\n", extensions[i++]);


    }
    gdk_pixbuf_loader_close(loader, NULL);

    return pixbuf;
}

static gboolean
plugin_unload(PurplePlugin * plugin)
{
    /* 
     * Ok, this is hell. I need to: Remove any icons from the IM windows. 
     * Disconnect signals Close and destroy roombrowsers/memory associated 
     * with Destroy all popups Remove chaticon buttons 
     */
    return TRUE;
}

static gboolean
plugin_load(PurplePlugin * plugin)
{
    init_chat_icons(plugin);
    //init_popups();
    //init_roombrowse(plugin);
    purple_debug_misc("plugin-load", "purple_conversations_get_handle(): %x\n", purple_conversations_get_handle());
    purple_signal_connect(purple_conversations_get_handle(), "conversation-created", plugin, PURPLE_CALLBACK(redo_im_window),
                          NULL);

    purple_signal_connect(purple_accounts_get_handle(), "info-updated", plugin, PURPLE_CALLBACK(update_info_cb), NULL);

    //purple_signal_connect(purple_conversations_get_handle(), "deleting-conversation", plugin, PURPLE_CALLBACK(clean_popup_stuff),
    //                      NULL);
    purple_prefs_add_none("/plugins/pecker");
    purple_prefs_add_none("/plugins/pecker/silly");

    extras_register_stock();

    return TRUE;
}

static PurplePluginPrefFrame *
get_plugin_pref_frame(PurplePlugin * plugin)
{
    PurplePluginPrefFrame *frame;
    PurplePluginPref *ppref;

    frame = purple_plugin_pref_frame_new();

    ppref =
        purple_plugin_pref_new_with_name_and_label("/plugins/pecker/silly", "Do you really want to turn any of this off? ;-)");
    purple_plugin_pref_frame_add(frame, ppref);

    return frame;
}

static PurplePluginUiInfo prefs_info = {
    get_plugin_pref_frame
};


static PurplePluginInfo info = {
    PURPLE_PLUGIN_MAGIC,
    PURPLE_MAJOR_VERSION,
    PURPLE_MINOR_VERSION,
    PURPLE_PLUGIN_STANDARD,
    PIDGIN_PLUGIN_TYPE,
    0,
    NULL,
    PURPLE_PRIORITY_DEFAULT,
    PECKER_EXTRAS_PLUGIN_ID,
    "Gay.com Extras (Woodpecker-GTK)",
    VERSION,
    "GUI-related additions for the gay.com protocol plugin.",
    "Current functionality provided by this plugin:\n1. Allows namelist sort order in rooms to be changed.\n2. Shows thumbnails for currently selected user in rooms.\n3. Popup displays bio when you hover over a name in the namelist.\n4. Popup shows bio when you hover over an IM tab.",
    "The Woodpecker Team",
    PURPLE_WEBSITE,
    plugin_load,
    plugin_unload,
    NULL,
    NULL,
    NULL,                       //&prefs_info,
    NULL
};

static void
init_plugin(PurplePlugin * plugin)
{
}

PURPLE_INIT_PLUGIN(history, init_plugin, info)
